﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using EPiServer.Security;
using System.Web;
using EPiServer.Personalization;
using EPiServer.Filters;
using System.Collections;

namespace EPiServer.Research.VirtualRoles
{
    public class ProfileMatchRole:VirtualRoleProviderBase
    {
        public string PropertyName { get; set; }
        public string PropertyValue { get; set; }
        public EPiServer.Filters.CompareCondition Condition { get; set; }
        public bool? CaseInsensitive { get; set; }

        public override void Initialize(string name, System.Collections.Specialized.NameValueCollection config)
        {
            base.Initialize(name, config);
            if(!string.IsNullOrEmpty(config["propertyname"])){
                PropertyName = config["propertyname"];
            }
            if(!string.IsNullOrEmpty(config["propertyvalue"])){
                PropertyValue = config["propertyvalue"];
            }
            if(!string.IsNullOrEmpty(config["condition"])){
                Condition = (CompareCondition)Enum.Parse(typeof(CompareCondition), config["condition"]);
            }
            CaseInsensitive = null;
            if (!string.IsNullOrEmpty(config["caseinsensitive"]))
            {
                CaseInsensitive = (bool?) bool.Parse(config["caseinsensitive"]);
                if (CaseInsensitive.Value) PropertyValue = PropertyValue.ToLower();
            }
        }

        public override bool IsInVirtualRole(System.Security.Principal.IPrincipal principal, object context)
        {
            if (HttpContext.Current == null) return false;
            if (EPiServer.Personalization.EPiServerProfile.Current == null) return false;
            if (PropertyName == null) return false;
            if (PropertyValue == null) return false;
            if (EPiServerProfile.Current[PropertyName] == null) return false;
            object obj = EPiServerProfile.Current[PropertyName];
            string strobj = obj.ToString();
            if (CaseInsensitive.HasValue && CaseInsensitive.Value) strobj = strobj.ToLower();
            switch (Condition)
            {
                case CompareCondition.Contained :
                    if (obj is string)
                    {
                        return strobj.Contains(PropertyValue);
                    }
                    if (obj is IList<string>)
                    {
                        return (obj as IList<string>).Contains(strobj);
                    }
                    break;
                case CompareCondition.EndsWith :
                    return strobj.EndsWith(PropertyValue);
                case CompareCondition.StartsWith:
                    return strobj.StartsWith(PropertyValue);
                case CompareCondition.Equal:
                    return strobj.Equals(PropertyValue);
                case CompareCondition.NotEqual:
                    return !strobj.Equals(PropertyValue);
                case CompareCondition.GreaterThan:
                    if (obj is int)
                    {
                        return ((int)obj) > int.Parse(PropertyValue);
                    }
                    if (obj is decimal)
                    {
                        return ((decimal)obj) > decimal.Parse(PropertyValue);
                    }
                    if (obj is double)
                    {
                        return ((double)obj) > double.Parse(PropertyValue);
                    }
                    if (obj is DateTime)
                    {
                        return ((DateTime)obj) > DateTime.Parse(PropertyValue);
                    }
                    break;
                case CompareCondition.LessThan:
                    if (obj is int)
                    {
                        return ((int)obj) < int.Parse(PropertyValue);
                    }
                    if (obj is decimal)
                    {
                        return ((decimal)obj) < decimal.Parse(PropertyValue);
                    }
                    if (obj is double)
                    {
                        return ((double)obj) < double.Parse(PropertyValue);
                    }
                    if (obj is DateTime)
                    {
                        return ((DateTime)obj) < DateTime.Parse(PropertyValue);
                    }
                    break;
                default:
                    return false;

            }
            return false;
            
        }
    }
}
